iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 29
1
自我挑戰組

Hey! UIKit, 做個朋友吧~系列 第 29

Day 29: 來玩拉和服腰帶轉圈圈吧UIScrollView

  • 分享至 

  • xImage
  •  

事實上拉和服腰帶轉圈圈的遊戲應該不是UIScrollView做的,理想飯麵。

Content

Size / Offset

要使scroll view可以捲動,必須設置一個比scroll view還要大的content view,不然我scroll view就可以完全顯示content view了,不知道是要捲屁捲。

let newScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
newScrollView.contentSize = CGSize(width: view.frame.width, height: 2100)

在上述範例中我們建立了一個跟螢幕大小相等的scroll view,並設定他的content view高度為2100(寬度等同於螢幕寬度)。
接下來建立一個高度一樣是2100的UIView,並把他加進scroll view裡,至於UIView的內容並不是這篇的重點,就不詳細實作了。

newScrollView.addSubview(adventureView)


而先前也說過,content view的原點會在捲動時調整,而scroll view就是藉由content view的原點偏移量來決定content view的顯示區塊的。所以我們可以利用setContentOffset(:animated:)這個function達到不用手指拖拉就捲動畫面的效果。
首先建立一個button,並設定一個function使他在點擊時觸發setContentOffset(
:animated:):

@objc func scrollAction(_ sender: UIButton) {
    newScrollView.setContentOffset(CGPoint(x: 0, y: CGFloat.random(in: 0...adventureView.frame.height - view.frame.height)), animated: true)
}


而在animate結束後,會發送訊息給delegate並呼叫scrollViewDidEndScrollingAnimation(_:)。

Inset

contentInset可以為你的內容設置一個相對於content view的safe area或scroll view邊緣的inset,預設狀況下UIKit會自動幫你調整內容的inset,預設值為UIEdgeInsetsZero。

newScrollView.contentInset = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)


adjustedContentInset是個get-only property,可以取得目前content view的UIEdgeInset。

content view的inset變化時的行為則由contentInsetAdjustmentBehavior
定義,他會回傳一個UIScrollView.ContentInsetAdjustmentBehavior的enum,預設值為UIScrollView.ContentInsetAdjustmentBehavior.automatic。
而當調整結束後,scroll view會呼叫adjustedContentInsetDidChange(),傳送訊息給delegate並呼叫scrollViewDidChangeAdjustedContentInset(_:)。

Layout

frameLayoutGuide及contentLayoutGuide都是get-only property,他會回傳一個UILayoutGuide,讓你可以根據scroll view的frame或是content view設定你內容的auto layout。

Configuring the Scroll View

Enable

isEnabled決定了你的scroll view能否被捲動,預設值為true。
isDirectionalLockEnabled則限制scroll view在同時間是否只能一維捲動,預設值為false。如果為true,則使用者垂直滑動的當下,水平滑動就會被鎖定,反之亦然。

不過如果使用者一開始就對角線滑動,那系統也沒轍了,這次就會讓他滑到高興為止。

而scroll view在app裡面非常的常見,只要頁面能滑爆的都是scroll view,所以其實瀏覽相片的功能也是scroll view喔!
但是到目前為止scroll view都是咻~的就滑過去了,要怎麼做出像瀏覽相片一樣的翻頁感呢?這就必須將isPagingEnabled設為true了。
當isPagingEnabled為true的時候,系統會自動幫你把content view依照scroll view的長寬切割,而使用者的滑動距離超過半個scroll view長寬的時候就會進行換頁。

Scroll To Top

scrollsToTop定義了使用者的scroll-to-top手勢是否能生效,預設為true。

bounces

bounces定義了當使用者爆滑一波到超出邊界時畫面會不會彈回,預設值為true。
true的狀況下就會像大家先前看到的範例一樣,超過邊界時有個彈回的動畫,而false的狀況不是不會彈回,而是根本就不會讓你爆滑一波到原點超出邊界==果然解決問題最快的方法94解決提出問題的人。

而在bounces為true的情況下,如果alwaysBounceVertical/alwaysBounceHorizontal也為true的話,即使content view的height/weight小於scroll view,也會允許垂直/水平拖拉(只是會馬上彈回去就是了)。

State

scroll view有幾個儲存狀態的get-only property:

  • isTracking追蹤了使用者的點擊動作。當使用者觸碰scroll view但還未滑動時,isTracking的值會變為true。
  • isDragging追蹤了使用者個捲動動作。當使用者開始捲動畫面一小段距離後,isDragging的值會變為true。
  • isDecelerating追蹤了scroll view減速的動作。當使用者停止捲動畫面,從減速到完全停止之前isDecelerating的值會變為true。

而減速的速率可以用decelerationRate指定,只有normal(下圖左)跟fast(下圖右)兩種,預設值為normal。

可以看到右邊很快就停下了,拉到我很焦慮啊啊啊~

因為太焦慮了,所以今天就到此為止(什麼跟什麼)。
下一回要來講如何管理scroll view啦~


上一篇
Day 28: SKT打RNG好精彩喔是不是啊UIScrollView
下一篇
Day 30: 終於結束的起點-UIScrollView
系列文
Hey! UIKit, 做個朋友吧~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言